package com.wkq.net.down

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
import androidx.core.app.NotificationManagerCompat

import com.wkq.net.IDownloadCallback
import com.wkq.net.IDownloadService


import com.wkq.net.RetrofitFileDownUtil
import com.wkq.net.RetrofitFileDownUtil.request
import com.wkq.net.callback.FileDownCallback
import io.reactivex.rxjava3.disposables.Disposable
import okhttp3.ResponseBody
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArrayList


/**
 * @Author: wkq
 * @Time: 2025/5/14 10:36
 * @Desc:
 */
class DownloadService : Service() {
    private val binder: IBinder = DownloadServiceImpl()
    private val callbacks = CopyOnWriteArrayList<IDownloadCallback?>()
    private val downloadTasks: MutableMap<String?, Disposable?> =
        ConcurrentHashMap<String?, Disposable?>()
    var builder: Notification.Builder? = null

    var mNotificationID: Int = 65536
    var pattern: LongArray = longArrayOf(100L, 400L, 100L, 400L)
    override fun onBind(intent: Intent?): IBinder? {
        if (checkNotifySetting(this)){
            val notification = initNotification(getApplicationContext(), mNotificationID, "下载", "文件下载中...")
            if (Build.VERSION.SDK_INT >= 26) startForeground(mNotificationID, notification)
        }
        return binder
    }

    private inner class DownloadServiceImpl : IDownloadService.Stub() {

        override fun registerCallback(callback: IDownloadCallback?) {
            if (callback != null && !callbacks.contains(callback)) {
                callbacks.add(callback)
            }
        }


        override fun unregisterCallback(callback: IDownloadCallback?) {
            callbacks.remove(callback)
        }


        override fun downloadFile(url: String?, type: String?, fileDirPath: String?) {
            val taskKey = getTaskKey(url, type)
            if (!downloadTasks.contains(taskKey)){
                RetrofitFileDownUtil.create(DownServiceApi::class.java)
                    .downFile(url)
                    .request<ResponseBody>(this@DownloadService, url=url,fileDir=fileDirPath ,callback=object : FileDownCallback {

                        override fun success(path: String?) {
                            notifyComplete(url, type, path)
                            cancelNotification(this@DownloadService)
                        }

                        override fun onFail(code: Int, msg: String?) {
                            notifyFailed(url, type, msg)
                            cancelNotification(this@DownloadService)
                        }

                        override fun onProgress(progress: Int) {
                            Log.e("下载进度:",progress.toString())
                            notifyProgress(url, type, progress);

//                            upProgress(this@DownloadService, progress)


                        }
                    })

            }

        }


        override fun cancelDownload(url: String?, type: String?) {
            val taskKey: String? = getTaskKey(url, type)
            val disposable = downloadTasks.remove(taskKey)
            if (disposable != null && !disposable.isDisposed()) {
                disposable.dispose()
            }
        }

    }

    override fun onDestroy() {
        super.onDestroy()
        // 取消所有回调注册
        callbacks.clear()
        // 取消所有下载任务
        for (disposable in downloadTasks.values) {
            if (disposable != null && !disposable.isDisposed) {
                disposable.dispose()
            }
        }
        super.onDestroy()
        cancelNotification(this)
    }


    private fun notifyProgress(url: String?, type: String?, progress: Int) {
        for (callback in callbacks) {
            try {
                callback!!.onProgressChanged(url, type, progress)
            } catch (e: RemoteException) {

            }
        }
    }

    private fun notifyComplete(url: String?, type: String?, filePath: String?) {
        for (callback in callbacks) {
            try {
                callback!!.onDownloadComplete(url, type, filePath)
            } catch (e: RemoteException) {

            }
        }
    }

    private fun notifyFailed(url: String?, type: String?, errorMsg: String?) {
        for (callback in callbacks) {
            try {
                callback!!.onDownloadFailed(url, type, errorMsg)
            } catch (e: RemoteException) {

            }
        }
    }



    private fun getTaskKey(url: String?, type: String?): String {
        return url + "_" + type
    }


    fun initNotification(
        mContext: Context, NotificationID: Int, title: String?, content: String?
    ): Notification? {
        mNotificationID = NotificationID
        val notification: Notification?
        val mNotificationManager =
            mContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager?
        if (mNotificationManager == null) return null
        //26(O版本)版本以上需要增加 channel
        if (Build.VERSION.SDK_INT >= 26) {
            try {
                val channel = NotificationChannel(mNotificationID.toString() + "", "下载", NotificationManager.IMPORTANCE_DEFAULT
                )
                channel.enableLights(true)
                channel.setLightColor(Color.GREEN)
                channel.setShowBadge(true)
                channel.enableVibration(true)
                channel.setDescription("文件下载中...")
                channel.setVibrationPattern(pattern)
                channel.setLightColor(Color.GREEN)
                channel.setLockscreenVisibility(Notification.FLAG_ONLY_ALERT_ONCE)
                mNotificationManager.createNotificationChannel(channel)
                builder = Notification.Builder(mContext, 2.toString() + "") //与channelId对应
            } catch (e: Exception) {
                Log.e("推送适配8.0异常*************:", e.message!!)
            }
        } else {
            builder = Notification.Builder(mContext) //与channelId对应
            if (Build.VERSION.SDK_INT > 16) {
                //设置显示时间
                builder!!.setShowWhen(true)
            }
        }
        if (builder == null) return null

        if (Build.VERSION.SDK_INT > 20) {
            //设置显示时间
            builder!!.setGroupSummary(false)
            builder!!.setGroup("下载")
        }
        builder!!.setSmallIcon(android.R.drawable.stat_sys_download)
        builder!!.setTicker(title)
        builder!!.setContentTitle(title)
        builder!!.setContentText(content)
        builder!!.setWhen(System.currentTimeMillis())
        //设置通知时间，一般设置的是收到通知时的System.currentTimeMillis()
        builder!!.setNumber(0)
        builder!!.setOngoing(true) //设置 只能代码调用取消
//        builder!!.setProgress(100, 0, false)
        builder!!.setOnlyAlertOnce(true) //设置只展示一次
        notification = builder!!.build()
        mNotificationManager.notify(mNotificationID, notification)
        return notification
    }

    /**
     * Notification 更新进度
     *
     * @param progress
     */
    fun upProgress(context: Context, progress: Int) {
        // 这里是处理 Notification 频繁更新卡顿问题.(部分手机可以开线程 小部分手机不兼容 华为p8 不兼容)
        if (progress % 5 == 0) {
            builder!!.setProgress(100, progress, false)
            val mNotificationManager =
                context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager?
            if (mNotificationManager != null) mNotificationManager.notify(
                mNotificationID, builder!!.build()
            )
        }
    }

    /**
     * 代码取消 Notification
     *
     * @param context
     */
    fun cancelNotification(context: Context?) {
        if (context == null) return
        val mNotificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager?
        if (mNotificationManager != null) mNotificationManager.cancel(mNotificationID)
        if (builder != null) builder = null
        if (Build.VERSION.SDK_INT >= 26) stopForeground(false)
        stopSelf()
    }

    fun checkNotifySetting(context: Context): Boolean {
        val currentApiVersion = Build.VERSION.SDK_INT
        if (currentApiVersion >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            val manager = NotificationManagerCompat.from(context)
            return manager.areNotificationsEnabled()
        } else {
            // 低于 API 19 的版本，默认认为通知已开启
            return true
        }
    }


}